using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Practices.CompositeUI.SmartParts;
using Microsoft.Practices.CompositeUI.Utility;

namespace SCSFContrib.CompositeUI.WPF
{
	/// <summary>
	/// A <see cref="ContentControl"/> that acts as a placeholder for a smart part.
	/// </summary>
	public class SmartPartPlaceholder : ContentControl, ISmartPartPlaceholder
	{
		/// <summary>
		/// Identifies the <see cref="SmartPart"/> dependency property.
		/// </summary>
		public static readonly DependencyProperty SmartPartProperty = DependencyProperty.Register("SmartPart",
			typeof(object),
			typeof(SmartPartPlaceholder),
			new FrameworkPropertyMetadata(SmartPartChanged));

		/// <summary>
		/// Identifies the <see cref="SmartPartName"/> dependency property.
		/// </summary>
		public static readonly DependencyProperty SmartPartNameProperty = DependencyProperty.Register("SmartPartName",
			typeof(string),
			typeof(SmartPartPlaceholder));

		/// <summary>
		/// Gets or sets the smart part to be displayed by this placeholder.
		/// </summary>
		public object SmartPart
		{
			get
			{
				return GetValue(SmartPartProperty);
			}
			set
			{
				Guard.ArgumentNotNull(value, "value");
				SetValue(SmartPartProperty, value);
			}
		}

		/// <summary>
		/// Gets or sets the name of the smart part to be displayed by this placeholder.
		/// </summary>
		public string SmartPartName
		{
			get
			{
				return GetValue(SmartPartNameProperty) as string;
			}
			set
			{
				SetValue(SmartPartNameProperty, value);
			}
		}

		/// <summary>
		/// Occurs whenever a smart part is shown by this placeholder.
		/// </summary>
		public event EventHandler<SmartPartPlaceHolderEventArgs> SmartPartShown;

		/// <summary>
		/// Raises the <see cref="SmartPartShown"/> event.
		/// </summary>
		protected virtual void OnSmartPartShown(SmartPartPlaceHolderEventArgs e)
		{
			Guard.ArgumentNotNull(e, "e");
			EventHandler<SmartPartPlaceHolderEventArgs> handler = SmartPartShown;

			if (handler != null)
			{
				handler(this, e);
			}
		}

		private static void SmartPartChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
		{
			Guard.ArgumentNotNull(e.NewValue, "value");
			SmartPartPlaceholder smartPartPlaceholder = dependencyObject as SmartPartPlaceholder;
			Debug.Assert(smartPartPlaceholder != null);
			smartPartPlaceholder.OnSmartPartShown(new SmartPartPlaceHolderEventArgs(e.NewValue));
		}
	}
}
